﻿
var getPositionInDocument = function(element){
			var position = {x : 0, y: 0};
				if(!element){
					return false;
				}
			if(element.offsetParent){
				do{
					position.x += element.offsetLeft;
					position.y += element.offsetTop;
				}while(element = element.offsetParent);
			}
			return position;
	}
	
var dragAble = function(object , options){
					if(!object)return;

					object = $(object).get(0);
					options = options || {
						handle : null , 
						dragStart : function(){} , 
						draging : function(){} , 
						dragStop : function(){}
					};

					if(!options.handle){options.handle = object;}
					$(options.handle).bind('mousedown' , startMove);
					var startPoint = {x:"" , y:""};	
					function startMove(evt){
						
						$(object).css({	
							position:'absolute' , 
							top : object.offsetTop +'px' , 
							left : object.offsetLeft + 'px' ,
							width : $(object).width(),
							zIndex : 10000
						});
						startPoint = {x : evt.pageX , y : evt.pageY};
						options['handle'].style.cursor = 'move';
						$(document).bind('mousemove' , moving);
						$(document).bind('mouseup' , stopMove);
						if(options.dragStart)options.dragStart();
					};

					function moving(evt){
						var curPoint = {x : evt.pageX , y : evt.pageY},
							d_x = curPoint.x - startPoint.x ,
							d_y = curPoint.y - startPoint.y ,
							pos_x = getPositionInDocument(object).x + d_x ,
						    pos_y = getPositionInDocument(object).y + d_y ;
							
						object.style.left = pos_x  + 'px';
						object.style.top = pos_y + 'px';
						startPoint = curPoint ;

						if(options.draging)options.draging(evt);
						return false;
					};

					function stopMove(evt){
						options['handle'].style.cursor = 'default';
						$(object).css({	
							position:'static' , 
							width : "100%",
							zIndex : 1
						});
						if(options.dragStop)options.dragStop();
						$(document).unbind();
					};
}

function Portal(selector){
	this.mark = document.createElement("div"); 
	this.element = $(selector).get(0);
	this.initial();
}

Portal.prototype = {
	initial : function(){
		var columns = $(this.element).children();
		var _this = this;
		$(columns).each(function(i,column){
			var portals = $(column).children();
			$(portals).each(function( i , portalDom){
				$(this).addClass("module");
				_this._bindPortalEvent(portalDom);
			});
		});
	},
	
	add : function(portalDom , columnIndex){
		var parent = $(this.element).children()[columnIndex];
		if(parent){
			var portalDom = $(portalDom).get(0);
			$(portalDom).appendTo(parent);
			$(portalDom).addClass("module");
			this._bindPortalEvent(portalDom);
			return true;
		}else{
			return false;
		}
	},
	
	remove : function(id){
		$("#" + id).remove();
		return true;
	},
	
	getResult : function(){
		var columns = $(this.element).children();
		var result = [];
		for(var i = 0 , len = columns.length ; i < len ; i++){
			var column = columns[i];
			var portals = $(column).children();
			result[i] = [];
			for( var j = 0 , jLen = portals.length ; j < jLen ; j++){
				result[i].push($(portals[j]).attr("id"));
			}
			result[i] = result[i].join(",");
		}
		result = result.join("|");
		return result;
		
	},
	
	_bindPortalEvent : function(portalDom){
		var _this = this;
		dragAble(portalDom , {
			"dragStart" : function(){
					portalDom.mark = _this.mark;
					$(portalDom.mark).css({
						"width" : "100%",
						"height" : $(portalDom).height(),
						"border" : "2px dotted black",
						"margin-bottom" :  $(portalDom).css("margin-bottom")
					});
					$(portalDom.mark).insertBefore(portalDom);
			},
				
			"draging" : function(){
					//当前拖动模块位置
					var curModulePos = {
						x : getPositionInDocument(portalDom).x ,
						y : getPositionInDocument(portalDom).y
					}
					
					var mostClosingModule = null;
					
					$(_this.element).children().each(function(){
						var columnPos = getPositionInDocument(this);
						if(curModulePos.x > columnPos.x && curModulePos.x < columnPos.x + $(this).width()){
							var childModules = $(this).find("div.module");
							if(childModules.length > 0 ){
								if(childModules.length == 1 && childModules[0] == portalDom){
									$(portalDom.mark).appendTo(this);
									return ;
								}
								$(childModules).each(function(){
									if(portalDom === this){
										return ;
									}
									var position = getPositionInDocument(this);
									var distance = {
										x : curModulePos.x - position.x ,
										y : curModulePos.y - position.y 
									}
									distance = Math.pow(distance.x,2) + Math.pow(distance.y,2);
									if(mostClosingModule){
										if(mostClosingModule.distance > distance){
											mostClosingModule = this;
											mostClosingModule.distance = distance;
										}
									}else{
										mostClosingModule = this;
										mostClosingModule.distance = distance;
									}
								});
								
								if(curModulePos.y > getPositionInDocument(mostClosingModule).y + $(mostClosingModule).height()/2){
									$(portalDom.mark).insertAfter(mostClosingModule);
								}else{
									$(portalDom.mark).insertBefore(mostClosingModule);
								}
							}else{
								$(portalDom.mark).appendTo(this);
							}
						}
					});
			},
				
			"dragStop" : function(){
					if(portalDom.mark){
						$(portalDom).insertAfter(portalDom.mark);
						$(portalDom.mark).remove();
						portalDom.mark = null;//for ie bad operate bug.
					}
			}
		});	
	}
}